<template>
  <view class="cart">
    <block v-if="cartList.length">
      <!-- 1.0 购物车列表 -->
      <view
        v-for="item in cartList"
        :key="item.goods_id"
        class="cart_item"
      >
        <!-- 1.1 选择按钮 -->
        <radio
          @tap="changeItemSelect(item.goods_id)"
          class="cart_item_radio"
          :checked="item.goods_select"
          color="#E03440"
        />
        <!-- 1.2 商品组件 -->
        <goodsItem :item="item" />
        <!-- 1.3 计数器 -->
        <view class="count">
          <view
            @tap="changeItemCount(item.goods_id,-1)"
            class="count_btn iconfont icon-jianshao"
          ></view>
          <text class="count_text">{{ item.goods_count }}</text>
          <view
            @tap="changeItemCount(item.goods_id,1)"
            class="count_btn iconfont icon-zengjia"
          ></view>
        </view>
      </view>
      <!-- 2.0 底部固定栏 -->
      <view class="bottom">
        <radio
          :checked="isSelectAll"
          color="#E03440"
          class="select_btn"
          @tap="changeSelectAll"
        />
        <text
          @tap="changeSelectAll"
          class="select_text"
        >全选</text>
        <text class="total_text">合计：</text>
        <text class="price">{{totalPrice}}</text>
        <view
          @tap="goToPayHandle"
          class="bottom_btn"
          :class="{disabled: totalPrice===0}"
        >去结算({{ totalCount }})</view>
      </view>
    </block>
    <view
      v-else
      class="cart_empty"
    >
      <image
        class="cart_empty_image"
        mode="widthFix"
        src="/static/cart_empty.gif"
      />
      <u-empty
        text="购物车为空"
        mode="car"
      ></u-empty>
      <navigator
        class="cart_empty_button"
        url="/pages/index/index"
        open-type="switchTab"
      >去首页看看</navigator>
    </view>
  </view>
</template>

<script>
/**
 * 1、布局
 * 	🔑 商品界面涉及到比较多操作，如果用组件，会出现比较多交互，不方便
 * 2、获取缓存购物车，渲染数据到页面
 * 	🔑 在onShow生命周期更新，不能在onLoad，如果在onLoad，用户再次添加商品时，购物车无法更新
 * 3、商品选中状态
 * 	3.1 点击勾选框，可切换选中/非选中状态
 * 		🔑需要在商品对象增加一个字段，叫checked，记录选中状态
 *		😈修改对象/数组，需要特殊赋值才能触发渲染
 *  3.2 商品如果全部选中，全选按钮为激活状态，否则全选按钮为空心
 * 5、商品可点击增加/减少按钮修改数量
 * 	5.1 当数量为1时，同时点击的是减号，提示是否删除商品
 * 4、全选/全不选
 * 	4.1 点击全选勾选框，所有商品自动勾选
 * 		🔑 遍历所有商品，把他们的checked属性修改为true
 * 	4.2 取消全选，所有商品全部取消勾选
 * 		🔑 遍历所有商品，把他们的checked属性修改为false
 * 6.结算
 * 	6.1 结算按钮上显示选中商品总数量
 * 		🔑 通过computed属性自动运算
 *  	😈 总价=勾选商品数量*价格
 * 	6.2 点击"去结算"跳转到结算页
 * 7、合计
 * 	7.1 合计价格为勾选商品的价格
 */
export default {
  data() {
    return {
      cartList: [],
      // isSelectAll: false,
    };
  },
  // onLoad 页面加载时触发。一个页面只会在加载时调用一次，如果页面被销毁，再加载的时候会再次触发。
  // onShow 应用启动，或从后台进入前台显示时触发
  // TabBar页打开后不会被销毁，所以TabBar的 onLoad 只触发一次。
  // 购物车页面打开的时候就需要获取最新的购物车数据，每次显示购物车页面都会触发 onShow 生命周期
  onShow() {
    console.log("cart购物车页的-----onShow");
    const cartList = uni.getStorageSync("cartList") || [];
    this.cartList = cartList;
  },
  // watch 监听变量的变化，触发内部函数
  watch: {
    // cartList(val){ },     🧨注意：这种写法只能监听到数组的第一层数组的变化，数组内部对象的变化监听不到
    // 🎉注意：深度监听
    cartList: {
      deep: true,
      handler(val) {
        // console.log("深度监听", val);
        uni.setStorageSync("cartList", val);
      },
    },
  },
  // computed 计算属性 => 计算出新的变量
  computed: {
    // 计算 全选状态
    isSelectAll() {
      return this.cartList.every((item) => item.goods_select);
    },
    // 计算 商品总价格
    totalPrice() {
      // 初始化总价
      let totalPrice = 0;
      // 遍历所有的选中商品
      this.cartList.forEach((item) => {
        if (item.goods_select) {
          // 总价计算：单价 * 数量 的累加
          totalPrice += item.goods_price * item.goods_count;
        }
      });
      // 返回总价
      return totalPrice;
    },
    totalCount() {
      // 情况1：淘宝App规则：选中勾勾有多少个
      // return this.cartList.filter((item) => item.goods_select).length;
      // 情况2：京东App规则：选中商品的 数量累加
      let totalCount = 0;
      this.cartList.forEach((item) => {
        if (item.goods_select) {
          totalCount += item.goods_count;
        }
      });
      return totalCount;
    },
  },
  methods: {
    // 有时候 uni-app 框架使用 index 索引的时候会出现异常，可以通过传递 id 并配合 findIndex 查找正确索引
    changeItemSelect(goods_id) {
      // 自己根据 goods_id 查找商品的索引
      const index = this.cartList.findIndex(
        (item) => item.goods_id === goods_id
      );
      // console.log(index);
      this.cartList[index].goods_select = !this.cartList[index].goods_select;

      // ❌全选状态写在这里的问题：用户必须点一下才会计算
      // this.isSelectAll = this.cartList.every((item) => item.goods_select);
    },
    //
    changeItemCount(goods_id, number) {
      // console.log(goods_id, number);
      // 查找索引
      const index = this.cartList.findIndex(
        (item) => item.goods_id === goods_id
      );

      // 特殊情况：如果数量是 1 并且是 减号操作
      if (this.cartList[index].goods_count === 1 && number === -1) {
        // 模态框提示
        return uni.showModal({
          content: "是否删除商品",
          confirmText: "删除",
          success: (res) => {
            if (res.confirm) {
              // console.log("用户点击确定");
              this.cartList.splice(index, 1);
            }
          },
        });
        // console.log("到达临界点，弹窗提示");
      }

      // 把索引对应的商品数量进行修改
      this.cartList[index].goods_count += number;
    },
    // 改变全选状态
    changeSelectAll() {
      // console.log(111);
      // ❌ computed 计算出来的变量不能通过赋值修改
      // this.isSelectAll = !this.isSelectAll;
      const bl = !this.isSelectAll;
      // ✅ 修改商品列表，最终影响到选中状态
      this.cartList.forEach((item) => {
        item.goods_select = bl;
      });
    },
    // 跳转到支付页
    goToPayHandle() {
      // 没有选中商品提示
      if (this.totalCount === 0) {
        uni.showToast({ title: "请选择结算商品", icon: "none" });
      } else {
        // console.log("跳转到结算页面");
        // 小程序的路由API：跳转普通页
        uni.navigateTo({ url: "/pages/pay/pay" });
      }
    },
  },
};
</script>

<style lang="scss">
.cart {
  padding-bottom: 83rpx;
}
// 1.0 购物车列表
.cart_item {
  display: flex;
  align-items: center;
  padding: 0 20rpx;
  position: relative;

  .cart_item_radio {
    margin: 0 20rpx;
  }
  .count {
    position: absolute;
    right: 0rpx;
    bottom: 0rpx;
    display: flex;
    padding: 20rpx;
    align-items: center;
    .iconfont {
      font-size: 40rpx;
    }
    .icon-jianshao {
      font-size: 44rpx;
    }
    .count_text {
      // 建议使用最小宽
      min-width: 80rpx;
      text-align: center;
    }
  }
}
// 2.0 底部固定栏
.bottom {
  height: 83rpx;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: #fff;
  border-top: 1rpx solid #ddd;
  display: flex;
  align-items: center;
  padding: 0 20rpx;
  .select_text {
    margin: 0 20rpx;
    color: #888;
    font-size: 22rpx;
  }

  .total_text {
    font-size: 26rpx;
  }

  .price {
    font-size: 28rpx;
    flex: 1;
  }

  .bottom_btn {
    font-size: 22rpx;
    width: 150rpx;
    height: 52rpx;
    border-radius: 26rpx;
    color: #fff;
    background-color: #ea4350;
    display: flex;
    justify-content: center;
    align-items: center;
    &.disabled {
      background-color: #ccc;
    }
  }
}

.cart_empty {
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  .cart_empty_image {
    width: 400rpx;
  }

  .cart_empty_button {
    margin-top: 20rpx;
    width: 400rpx;
    height: 60rpx;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: #ea4350;
    color: #fff;
    border-radius: 30rpx;
  }
}
</style>